<?php

namespace app\service;

use app\common\BaseService;
use app\model\Task as TaskModel;
use app\model\TaskFile as TaskFileModel;
use app\model\TaskNote as TaskNoteModel;
use app\model\NoteFile as NoteFileModel;
use think\facade\Db;

class TaskService extends BaseService
{
  public static function getInstance(): TaskService
  {
    return parent::getInstance();
  }

  public static function getModel(): TaskModel
  {
    return TaskModel::getInstance();
  }

  public static function getFileModel(): TaskFileModel
  {
    return TaskFileModel::getInstance();
  }

  public static function getNoteModel(): TaskNoteModel
  {
    return TaskNoteModel::getInstance();
  }

  public static function getNoteFileModel(): NoteFileModel
  {
    return NoteFileModel::getInstance();
  }

  /*
   * 根据ID获取商品表
   */
  public static function getTaskById($id) {
    return self::getModel()
      ->where('id', '=', $id)
      ->find()
      ->toArray();
  }

  /*
   * 根据condition获取商品
   */
  public static function getTaskByCondition ($conditions = [], $order = ['id' => 'asc']) {
    $query = self::getModel();
    foreach ($conditions as $item) {
      list($field, $value, $op) = $item;
      if (!$op) {
        $op = '=';
      }
      $query = $query->where($field, $op, $value);
    }
    $query = $query->order($order);
    return $query->select()->toArray();
  }
  /*
   * 连用户表/项目查询信息
   */
  public static function getTaskJoinProject($conditions = [], $order= ['t.id' => 'desc'], $orConditions = []) {
    $query = Db::name('task')
      ->alias('t')
      ->field('t.*,IF((t.`dev_status`=1 OR t.`dev_status`=2 OR t.`dev_status`=4) AND t.`status` = 1 , 1, t.`dev_status`) AS new_status,u1.truename as assign_user, u2.truename as task_user, p.project_name, p.project_user_ids')
      ->join('user u1', 'u1.id = t.assign_user_id', 'LEFT')
      ->join('project p', 'p.id = t.project_id', 'LEFT')
      ->join('user u2', 'u2.id = t.task_user_id', 'LEFT');
    foreach ($conditions as $item) {
      list($field, $value, $op) = $item;
      if (!$op) {
        $op = '=';
      }
      if ($field === 't.is_check' && $orConditions) {
        $query = $query->whereOr([$orConditions]);
      } else {
        $query = $query->where($field, $op, $value);
      }
    }
    $query = $query->order($order);
    return $query->select()->toArray();
  }

  /*
   * 新增任务
   */
  public static function createTask($data) {
    // 查看是否有同名
    $haveTask = self::getModel()
      ->where('task_name','=',$data['task_name'])
      ->where('project_id','=',$data['project_id'])
      ->where('task_user_id','=',$data['task_user_id'])
      ->where('estimated_date','=',$data['estimated_date'])
      ->select()
      ->toArray();
    if ($haveTask) {
      return ['status' => false, 'msg' => '任务已存在'];
    }
    // 新增到task
    $taskInsert = [
      'project_id' => $data['project_id'],
      'task_name' => $data['task_name'],
      'assign_user_id' => $data['assign_user_id'],
      'task_user_id' => $data['task_user_id'],
      'estimated_date' => $data['estimated_date'],
      'desc' => $data['desc'],
      'is_check' => $data['is_check'],
      'check_status' => 0,
      'weight' => 1,
      'progress' => 0,
      'dev_status' => 1,
      'status' => 1,
      'insert_time' => date('Y-m-d H:i:s'),
      'last_update_time' => date('Y-m-d H:i:s')
    ];
    // 新增到task_file
    $taskFileInsert = [];
    if ($data['file_url']) {
      foreach ($data['file_url'] as $file) {
        $taskFileInsert[] = [
          'task_id' => '',
          'file_name' => $file['name'],
          'file_url' => explode('https://if.prowealthgroup.cn/task-produce', $file['url'])[1],
          'status' => 1,
          'insert_time' => date('Y-m-d H:i:s'),
          'last_update_time' => date('Y-m-d H:i:s')
        ];
      }
    }
    $taskList = self::getModel()->field('id,weight')->where('weight','>',0)->select()->toArray();
    foreach ($taskList as &$tv) {
      $tv['weight'] += 1;
    }
    self::getModel()->startTrans();
    try {
      // 编辑task权重
      $res = self::getModel()->saveAll($taskList);
      if ($res === false) {
        throw new \Exception('权重修改失败');
      }
      // 新增task表
      $res1 = self::getModel()->insertGetId($taskInsert);
      if ($res1 === false) {
        throw new \Exception('新增失败');
      }
      // 新增task_file
      if ($res1 && $taskFileInsert) {
        // 新增task_file表
        foreach ($taskFileInsert as &$v) {
          $v['task_id'] = $res1;
        }
        $res2 = self::getFileModel()->saveAll($taskFileInsert);
        if ($res2 === false) {
          throw new \Exception('新增file失败');
        }
      }
      self::getModel()->commit();
      return ['status' => true, 'msg' => 'ok'];
    } catch (\Exception $e) {
      self::getModel()->rollback();
      return ['status' => false, 'msg' => $e->getMessage()];
    }
  }

  /*
   * 编辑任务
   */
  public static function updateTask($id, $data) {
    $task = self::getModel()->find($id)->toArray();
    $updateTask = [];
    $updateWeight = [];

    // 查看是否有同名
    $haveTask = self::getModel()
      ->where('id', '<>', $id)
      ->where('task_name','=',isset($data['task_name']) ? $data['task_name'] : $task['task_name'])
      ->where('project_id','=',isset($data['project_id']) ? $data['project_id'] : $task['project_id'])
      ->where('task_user_id','=',isset($data['task_user_id']) ? $data['task_user_id'] : $task['task_user_id'])
      ->where('estimated_date','=',isset($data['estimated_date']) ? $data['estimated_date'] : $task['estimated_date'])
      ->select()
      ->toArray();
    if ($haveTask) {
      return ['status' => false, 'msg' => '任务已存在'];
    }

    // 原本任务未完成
    if ($task['status'] === 1) {
      // 任务变更为完成
      if ((($data['is_check'] && $data['check_status'] === 3) || !$data['is_check']) && $data['dev_status'] === 4) {
        $updateTask['weight'] = null;
        $updateTask['status'] = 2;
        $updateTask['complete_date'] = date('Y-m-d H:i:s');
        // 其他任务权限-1
        $allChange = self::getInstance()->getTaskByCondition([['weight', $task['weight'], '>'], ['id', $id, '<>']], ['weight' => 'asc']);
        foreach ($allChange as $cv) {
          $updateWeight[] = [
            'id' => $cv['id'],
            'weight' => $cv['weight'] - 1
          ];
        }
      } else {
        // 变更为暂缓
        if ($task['dev_status'] !== 3 && $data['dev_status'] === 3) {
          // 任务设为暂缓 =》 大于该权重的-1 该权重改为空
          $updateTask['weight'] = null;
          $allChange = self::getInstance()->getTaskByCondition([['weight', $task['weight'], '>']], ['weight' => 'asc']);
          foreach ($allChange as $cv) {
            $updateWeight[] = [
              'id' => $cv['id'],
              'weight' => $cv['weight'] - 1
            ];
          }
        // 取消暂缓
        } else if ($task['dev_status'] === 3 && $data['dev_status'] !== 3){
          // 置顶
          $updateTask['weight'] = 1;
          $allChange = self::getInstance()->getTaskByCondition([['weight', 0, '>']], ['weight' => 'asc']);
          foreach ($allChange as $cv) {
            $updateWeight[] = [
              'id' => $cv['id'],
              'weight' => $cv['weight'] + 1
            ];
          }
        }
      }
    }
    // 原本任务已完成
    else {
      // 取消任务完成
      if ($data['dev_status'] !== 4 || ($data['is_check'] && $data['check_status'] !== 3)) {
        $updateTask['status'] = 1;
        $updateTask['complete_date'] = null;
        // 判断是否设为暂缓 否=》设为置顶
        if ($data['dev_status'] !== 3) {
          $updateTask['weight'] = 1;
          $allChange = self::getInstance()->getTaskByCondition([['weight', 0, '>'], ['id', $id, '<>']], ['weight' => 'asc']);
          foreach ($allChange as $cv) {
            $updateWeight[] = [
              'id' => $cv['id'],
              'weight' => $cv['weight'] + 1
            ];
          }
        }
      }
    }
    isset($data['dev_status']) ? $updateTask['dev_status'] = $data['dev_status'] : true;
    isset($data['project_id']) ? $updateTask['project_id'] = $data['project_id'] : true;
    isset($data['task_name']) ? $updateTask['task_name'] = $data['task_name'] : true;
    isset($data['task_user_id']) ? $updateTask['task_user_id'] = $data['task_user_id'] : true;
    isset($data['estimated_date']) ? $updateTask['estimated_date'] = $data['estimated_date'] : true;
    isset($data['is_check']) ? $updateTask['is_check'] = $data['is_check'] : true;
    isset($data['check_status']) ? $updateTask['check_status'] = $data['check_status'] : true;
    isset($data['desc']) ? $updateTask['desc'] = $data['desc'] : true;

    // 修改文件
    $taskFileInsert = [];
    if (isset($data['file_url'])) {
      foreach ($data['file_url'] as $file) {
        $taskFileInsert[] = [
          'task_id' => $id,
          'file_name' => $file['name'],
          'file_url' => explode('https://if.prowealthgroup.cn/task-produce', $file['url'])[1],
          'status' => 1,
          'insert_time' => date('Y-m-d H:i:s'),
          'last_update_time' => date('Y-m-d H:i:s')
        ];
      }
    }

    // 修改日志
    $taskLogInsert = [];
    $logPathInsert = [];
    if (isset($data['editLog']) && $data['editLog'] && ($data['editLog']['text'] || $data['editLog']['picture'])) {
      $taskLogInsert = [
        'task_id' => $id,
        'note' => isset($data['editLog']['text']) ? $data['editLog']['text'] : '',
        'user_id' => $data['editLog']['user_id'],
        'status' => 1,
        'insert_time' => date('Y-m-d H:i:s'),
        'last_update_time' => date('Y-m-d H:i:s')
      ];
      foreach ($data['editLog']['picture'] as $pic) {
        $logPathInsert[] = [
          'task_note_id' => '',
          'file_name' => $pic['name'],
          'file_url' => explode('https://if.prowealthgroup.cn/task-produce', $pic['url'])[1],
          'status' => 1,
          'insert_time' => date('Y-m-d H:i:s'),
          'last_update_time' => date('Y-m-d H:i:s')
        ];
      }
    }

    self::getModel()->startTrans();
    try {
      // 编辑task表
      if ($updateTask) {
        $res = self::getModel()->where('id', '=', $id)->save($updateTask);
        if ($res === false) {
          throw new \Exception('编辑失败');
        }
      }
      // 编辑task表其他权重
      if ($updateWeight) {
        $res1 = self::getModel()->saveAll($updateWeight);
        if ($res1 === false) {
          throw new \Exception('编辑权重失败');
        }
      }
      if(isset($data['file_url'])) {
        // 删除taskFile
        $res2 = self::getFileModel()
          ->where('task_id', '=', $id)
          ->delete();
        if ($res2 === false) {
          throw new \Exception('删除file失败');
        }
        // 新增taskFile
        $res3 = self::getFileModel()->saveAll($taskFileInsert);
        if ($res3 === false) {
          throw new \Exception('新增file失败');
        }
      }
      // 新增任务日志
      if ($taskLogInsert) {
        $res4 = self::getNoteModel()->insertGetId($taskLogInsert);
        if ($res4 === false) {
          throw new \Exception('新增日志失败');
        }
      }
      if ($logPathInsert && $res4) {
        foreach ($logPathInsert as &$v) {
          $v['task_note_id'] = $res4;
        }
        $res5 = self::getNoteFileModel()->saveAll($logPathInsert);
        if ($res5 === false) {
          throw new \Exception('新增日志文件失败');
        }
      }
      self::getModel()->commit();
      return ['status' => true, 'msg' => 'ok'];
    } catch (\Exception $e) {
      self::getModel()->rollback();
      return ['status' => false, 'msg' => $e->getMessage()];
    }
  }

  /**
   * 删除任务
   */
  public static function deleteTask($id) {
    $task = self::getModel()->find($id)->toArray();
    $updateWeight = [];
    if ($task['weight']) {
      // 其他任务权限-1
      $allChange = self::getInstance()->getTaskByCondition([['weight', $task['weight'], '>'], ['id', $id, '<>']], ['weight' => 'asc']);
      foreach ($allChange as $cv) {
        $updateWeight[] = [
          'id' => $cv['id'],
          'weight' => $cv['weight'] - 1,
          'last_update_time' => date('Y-m-d H:i:s')
        ];
      }
    }

    self::getModel()->startTrans();
    try {
      $res = self::getModel()
        ->where('id', '=', $id)
        ->delete();
      if ($res === false) {
        return ['status' => false, 'msg' => '删除失败'];
      }
      if ($res) {
        $res2 = self::getFileModel()
          ->where('task_id', '=', $id)
          ->delete();
        if ($res2 === false) {
          throw new \Exception('删除file失败');
        }
      }
      // 编辑task表其他权重
      if ($updateWeight) {
        $res1 = self::getModel()->saveAll($updateWeight);
        if ($res1 === false) {
          throw new \Exception('编辑权重失败');
        }
      }
      self::getModel()->commit();
      return ['status' => true, 'msg' => 'ok'];
    } catch (\Exception $e) {
      self::getModel()->rollback();
      return ['status' => false, 'msg' => $e->getMessage()];
    }
  }

  /**
   * 获取任务文件
   */
  public static function getTaskFileByCondition($conditions = [], $order = ['id' => 'asc']) {
    $query = self::getFileModel();
    foreach ($conditions as $item) {
      list($field, $value, $op) = $item;
      if (!$op) {
        $op = '=';
      }
      $query = $query
        ->where($field, $op, $value);
    }
    $query = $query->order($order);
    return $query->select()->toArray();
  }

  /**
   * 获取日志详情
   */
  public static function getTaskFileJoinUser($conditions = [], $order = ['n.id' => 'asc']) {
    $query = Db::name('task_note')
      ->alias('n')
      ->field('n.*,u.truename')
      ->join('user u', 'u.id = n.user_id', 'LEFT');
    foreach ($conditions as $item) {
      list($field, $value, $op) = $item;
      if (!$op) {
        $op = '=';
      }
      $query = $query->where($field, $op, $value);
    }
    $query = $query->order($order);
    return $query->select()->toArray();
  }

  /**
   * 获取日志路径
   */
  public static function getNotePathByCondition($conditions = [], $order = ['id' => 'asc']) {
    $query = self::getNoteFileModel();
    foreach ($conditions as $item) {
      list($field, $value, $op) = $item;
      if (!$op) {
        $op = '=';
      }
      $query = $query
        ->where($field, $op, $value);
    }
    $query = $query->order($order);
    return $query->select()->toArray();
  }

  /**
   * 改变权重
   */
  public static function updateWeight($id, $type, $weight) {
    // 获取修改任务
    $task = self::getModel()->find($id)->toArray();
    // 任务本身权限大于改后权重（任务上移） =》 修改改后权重之后的数据
    // 改后权重大于任务本身权限（任务下移） =》 修改本身权重之后的数据
    $weightChange = $task['weight'] > $weight ? $weight : $task['weight'];
    // 获取需要修改权重的数据
    $allWeight = self::getInstance()->getTaskByCondition([['weight', $weightChange, '>=']], ['weight' => 'asc']);
    // 改后数据
    $newWeight = [];
    $isChange = 0;
    foreach ($allWeight as $value) {
      // 不是该数据
      if ($value['id'] != $id) {
        // 上移（所有数据下移 +1）
        if ($type === 'up') {
          $newWeight[] = [
            'id' => $value['id'],
            'weight' => $isChange ? $value['weight'] :$value['weight'] + 1,
            'last_update_time' => date('Y-m-d H:i:s')
          ];
        // 下移（所有数据上移 -1）
        } else {
          $newWeight[] = [
            'id' => $value['id'],
            'weight' => $value['weight'] <= $weight ? $value['weight'] - 1 : $value['weight'],
            'last_update_time' => date('Y-m-d H:i:s')
          ];
        }
      } else {
        $newWeight[] = [
          'id' => $id,
          'weight' => $weight,
          'last_update_time' => date('Y-m-d H:i:s')
        ];
        $isChange = 1;
      }
    }
    // 批量修改task表
    $res = self::getModel()->saveAll($newWeight);
    if ($res === false) {
      return ['status' => false, 'msg' => '修改失败'];
    }
    return ['status' => true, 'msg' => '修改成功'];

  }


}